<!DOCTYPE html>
<html>
<head>
  <style type="text/css">
    #animatable {
      position: absolute;
      left: 0;
      top: 0;
      height: 100px;
      width: 100px;
      background-color: green;
      border-radius: 10px;
      transition: transform 1s;
    }

    #poster {
      font-family: 'Georgia', serif;
      font-size: 36px;
      font-weight: bold;
      text-align: center;
      margin-top: 28px;
    }

    #text {
      position: absolute;
      left: 20px;
      top: 400px;
    }

    #text > p {
      font-family: 'Verdana', serif;
      font-size: 12px;
      font-weight: bold;
    }
  </style>
  <script type="text/javascript">
    const initialValues = [
      "translate3d(100px, 100px, 0px)",
      "rotate3d(0, 1, 0, 0deg)",
      "scale3d(1, 1, 1)",
      "perspective(10000px)",
      "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)",
      "skew(0deg, 0deg)"
    ];

    const targetValues = [
      "translate3d(250px, 250px, 0px)",
      "rotate3d(0, 1, 0, 30deg)",
      "scale3d(2, 2, 2)",
      "perspective(200px)",
      "matrix3d(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)",
      "skew(10deg, 10deg)"
    ];

    var i = 1;
    var iterations = Math.pow(2, initialValues.length);
    var oldStyle = "";

    // For the buffon needle experiment below.
    var hits = 0;
    var trials = 0;
    var estimate = 0;

    function triggerTransition()
    {
      var style = "";
      var elem = document.getElementById("animatable");

      for (var j = 0; j < initialValues.length; ++j) {
        if (j > 0)
          style += " ";

        var values = initialValues;
        if (Math.floor(i / Math.pow(2, j)) % 2 == 1)
          values = targetValues;

        style += values[j];
      }

      elem.style.transform = style;
      i++;

      document.getElementById("from").innerHTML = "From:<br> " + oldStyle;
      document.getElementById("to").innerHTML = "To:<br> " + style;
      document.getElementById("estimate").innerHTML = "Buffon estimate of pi after " + trials.toString() + " needle drops:<br>" + estimate.toString();

      oldStyle = style;

      if (i < iterations)
        setTimeout(triggerTransition, 1000);
    }

    function buffonStep()
    {
      for (var step = 0; step < 100000; ++step) {
        var x = 2.0 * Math.random();
        x = Math.min(x, 2.0 - x);

        if (Math.cos(Math.PI * Math.random() * 0.5) > x)
          hits++;

        trials++;

        if (hits > 0)
          estimate = 2 * trials / hits;
      }

      if (i < iterations)
        setTimeout(buffonStep, 0);
    }

    function startExperiment()
    {
      triggerTransition();
      buffonStep();
    }

    window.addEventListener('load', startExperiment, false);
  </script>
</head>
<body>
<div id="animatable"><p id="poster">Hi!</p></div>
<div id="text">
  <p id="from">From:</p>
  <p id="to">To:</p>
  <p id="estimate">Estimate:</p>
</div>
</body>
</html>

